package com.yingxin.yxerp.module.dingtalk.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiChatSendRequest;
import com.dingtalk.api.request.OapiMediaUploadRequest;
import com.dingtalk.api.response.OapiChatSendResponse;
import com.dingtalk.api.response.OapiMediaUploadResponse;
import com.taobao.api.ApiException;
import com.taobao.api.FileItem;
import com.yingxin.yx.framework.commons.constant.CommonConst;
import com.yingxin.yx.framework.commons.exception.BizException;
import com.yingxin.yxerp.module.dingtalk.config.AppConfig;
import com.yingxin.yxerp.module.dingtalk.constant.MsgTypeEnum;
import com.yingxin.yxerp.module.dingtalk.constant.UrlConstant;
import com.yingxin.yxerp.module.dingtalk.service.MessageNotificationService;
import com.yingxin.yxerp.module.dingtalk.service.WeComMessageNotificationService;
import com.yingxin.yxerp.module.dingtalk.util.AccessTokenUtil;
import com.yingxin.yxerp.module.dingtalk.vo.DingTalkMessage;
import com.yingxin.yxerp.module.sys.entity.DingMessageSet;
import com.yingxin.yxerp.module.sys.entity.enums.MessageSendingOptionsType;
import com.yingxin.yxerp.module.sys.service.IDingMessageSetService;
import com.yingxin.yxerp.module.sys.service.IMessageSendingOptionsService;
import com.yingxin.yxerp.module.sys.vo.resp.MessageSendingOptionsRespVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;

@Slf4j
@Service
public class MessageNotificationServiceImpl implements MessageNotificationService {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private IDingMessageSetService dingMessageSetService;

    @Autowired
    private WeComMessageNotificationService weComMessageNotificationService;

    @Autowired
    private IMessageSendingOptionsService optionsService;

    @Override
    public void sendGroupFileMsg( String path,String chatType ) {
        MessageSendingOptionsRespVo optionsRespVo = optionsService.getOne();
        if( optionsRespVo.getOptions().trim().equals( MessageSendingOptionsType.ONE.getType().trim() ) ) {
            String fileId = uploadFile(path);
            DingTalkMessage dingTalkMessage = new DingTalkMessage();
            dingTalkMessage.setMsgType(MsgTypeEnum.FILE.getMsgType());
            DingTalkMessage.FileMessage fileMessage = new DingTalkMessage.FileMessage();
            fileMessage.setMediaId(fileId);
            dingTalkMessage.setFile(fileMessage);
            sendGroupMessage(dingTalkMessage, chatType);
        } else if( optionsRespVo.getOptions().trim().equals( MessageSendingOptionsType.TWO.getType().trim() ) ) {
            weComMessageNotificationService.sendGroupFileMsg( path, chatType );
        }
    }

    @Override
    public void sendGroupImgMsg(String filePath, String chatType) {
        MessageSendingOptionsRespVo optionsRespVo = optionsService.getOne();
        if( optionsRespVo.getOptions().trim().equals( MessageSendingOptionsType.ONE.getType().trim() ) ) {
            String fileId = uploadImage(filePath);
            DingTalkMessage dingTalkMessage = new DingTalkMessage();
            dingTalkMessage.setMsgType(MsgTypeEnum.IMAGE.getMsgType());
            DingTalkMessage.FileMessage fileMessage = new DingTalkMessage.FileMessage();
            fileMessage.setMediaId(fileId);
            dingTalkMessage.setFile(fileMessage);
            sendGroupMessage(dingTalkMessage, chatType);
        } else if( optionsRespVo.getOptions().trim().equals( MessageSendingOptionsType.TWO.getType().trim() ) ) {
            weComMessageNotificationService.sendGroupImgMsg( filePath, chatType );
        }
    }

    @Override
    public void sendGroupTextMsg(String content, String chatType) {
        MessageSendingOptionsRespVo optionsRespVo = optionsService.getOne();
        if( optionsRespVo.getOptions().trim().equals( MessageSendingOptionsType.ONE.getType().trim() ) ){
            DingTalkMessage dingTalkMessage = new DingTalkMessage();
            dingTalkMessage.setMsgType(MsgTypeEnum.TEXT.getMsgType());
            DingTalkMessage.TextMessage textMessage = new DingTalkMessage.TextMessage();
            textMessage.setContent(content);
            dingTalkMessage.setText(textMessage);
            sendGroupMessage(dingTalkMessage,chatType);
        } else if( optionsRespVo.getOptions().trim().equals( MessageSendingOptionsType.TWO.getType().trim() ) ) {
            weComMessageNotificationService.sendGroupTextMsg( content, chatType );
        }
    }

    /**
     * 发送群消息
     */
    public void sendGroupMessage(DingTalkMessage dingTalkMessage,String chatType) {
        DingMessageSet set = dingMessageSetService.getDingMessageSetByType(chatType);
        if (null != set && StringUtils.isNotEmpty(set.getChatId()) && CommonConst.TRUE.equals(set.getIsSend())){
            String accessToken = AccessTokenUtil.getAccessToken(appConfig.getAppKey(), appConfig.getAppSecret());
            // 发送群消息
            String messageId = sendChatMessage(set.getChatId(), accessToken, dingTalkMessage);
            // 发送日志
            /*
            DingSendLog vo = new DingSendLog();
            BeanUtils.copyProperties(set,vo);
            vo.setDingMsg(JSON.toJSONString(dingTalkMessage));
            vo.setMessageId(messageId);
            dingSendLogService.create(vo);
            */
        }
    }


    public String uploadFile(String filePath) {
        String accessToken = AccessTokenUtil.getAccessToken(appConfig.getAppKey(), appConfig.getAppSecret());
        DingTalkClient client = new DefaultDingTalkClient(UrlConstant.UPLOAD_MEDIA_URL);
        OapiMediaUploadRequest req = new OapiMediaUploadRequest();
        req.setType("file");
        File file1 = new File(filePath);
        FileItem item = new FileItem(file1);
        req.setMedia(item);
        try {
            OapiMediaUploadResponse rsp = client.execute(req, accessToken);
            if (rsp.isSuccess()) {
                //file1.delete();
                return rsp.getMediaId();
            } else {
                log.error(rsp.getErrmsg());
                throw new BizException("钉钉附件发送失败");
            }
        } catch (ApiException e) {
            throw new BizException("钉钉附件发送失败");
        }
    }

    public String uploadImage(String filePath) {
        String accessToken = AccessTokenUtil.getAccessToken(appConfig.getAppKey(), appConfig.getAppSecret());
        DingTalkClient client = new DefaultDingTalkClient(UrlConstant.UPLOAD_MEDIA_URL);
        OapiMediaUploadRequest req = new OapiMediaUploadRequest();
        req.setType("image");
        FileItem item = new FileItem(filePath);
        req.setMedia(item);
        try {
            OapiMediaUploadResponse rsp = client.execute(req, accessToken);
            if (rsp.isSuccess()) {
                return rsp.getMediaId();
            } else {
                log.error(rsp.getErrmsg());
                throw new BizException("钉钉附件发送失败");
            }
        } catch (ApiException e) {
            throw new BizException("钉钉附件发送失败");
        }
    }

    /**
     * 发送群消息
     *
     * @param chatId
     * @param accessToken
     * @param dingTalkMessage
     * @return
     */
    private String sendChatMessage(String chatId, String accessToken, DingTalkMessage dingTalkMessage) {
        DingTalkClient client = new DefaultDingTalkClient(UrlConstant.SEND_CHAT_MESSAGE);
        OapiChatSendRequest req = new OapiChatSendRequest();
        req.setChatid(chatId);
        OapiChatSendRequest.Msg msg = buildOapiChatSendRequestMsg(dingTalkMessage);
        req.setMsg(msg);
        try {
            log.info("sendChatMessage request params req: {}, accessToken: {}", JSONObject.toJSON(req), accessToken);
            OapiChatSendResponse rsp = client.execute(req, accessToken);
            log.info("sendChatMessage rsp: {}", JSONObject.toJSON(rsp));
            if (rsp.isSuccess()) {
                String messageId = rsp.getMessageId();
                return messageId;
            } else {
                throw new BizException(rsp.getErrorCode(), rsp.getErrmsg());
            }
        } catch (ApiException e) {
            e.printStackTrace();
            throw new BizException(e.getErrCode(), e.getErrMsg());
        }
    }


    /**
     * 构建钉钉消息
     *
     * @param dingTalkMessage
     * @return
     */
    private OapiChatSendRequest.Msg buildOapiChatSendRequestMsg(DingTalkMessage dingTalkMessage) {
        // 根据消息类型构建不同的消息
        if (MsgTypeEnum.LINK.getMsgType().equals(dingTalkMessage.getMsgType())) {
            // 获取前端请求的链接消息
            DingTalkMessage.LinkMessage linkMessage = dingTalkMessage.getLink();
            // 群消息
            OapiChatSendRequest.Msg msg = new OapiChatSendRequest.Msg();
            msg.setMsgtype(dingTalkMessage.getMsgType());
            // 构建链接消息
            OapiChatSendRequest.Link link = new OapiChatSendRequest.Link();
            link.setMessageUrl(linkMessage.getMessageUrl());
            link.setPicUrl(linkMessage.getPicUrl());
            link.setText(linkMessage.getText());
            link.setTitle(linkMessage.getTitle());
            msg.setLink(link);
            return msg;
        }else if (MsgTypeEnum.FILE.getMsgType().equals(dingTalkMessage.getMsgType())){
            OapiChatSendRequest.Msg msg = new OapiChatSendRequest.Msg();
            OapiChatSendRequest.File file = new OapiChatSendRequest.File();
            file.setMediaId(dingTalkMessage.getFile().getMediaId());
            msg.setFile(file);
            msg.setMsgtype("file");
            return msg;
        }else if (MsgTypeEnum.TEXT.getMsgType().equals(dingTalkMessage.getMsgType())){
            OapiChatSendRequest.Msg msg = new OapiChatSendRequest.Msg();
            msg.setMsgtype(dingTalkMessage.getMsgType());
            OapiChatSendRequest.Text text =  new OapiChatSendRequest.Text();
            text.setContent(dingTalkMessage.getText().getContent());
            msg.setText(text);
            return msg;
        }else if (MsgTypeEnum.IMAGE.getMsgType().equals(dingTalkMessage.getMsgType())){
            OapiChatSendRequest.Msg msg = new OapiChatSendRequest.Msg();
            OapiChatSendRequest.Image img = new OapiChatSendRequest.Image();
            img.setMediaId(dingTalkMessage.getFile().getMediaId());
            msg.setImage(img);
            msg.setMsgtype("image");
            return msg;
        }else {
            // TODO: 2021/6/30 build other message
            throw new RuntimeException("msgType not match");
        }
    }
}
